package com.zhu.utils;

import com.zhu.pojo.SystemData;
import com.zhu.vo.server.CPUVo;
import com.zhu.vo.server.JVMVo;
import com.zhu.vo.server.MemVo;
import com.zhu.vo.server.ServerVo;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

public class SystemUtils {

    public static SystemData getSystemInfo(){
        SystemData data = new SystemData();
        data.setCpuVo(printlnCpuInfo());
        data.setMemVo(MemInfo());
        data.setJvmVo(setJvmInfo());
        data.setServerVo(setSysInfo());
        return data;
    }

    private static CPUVo printlnCpuInfo() {
        CPUVo cpuVo = new CPUVo();
        //System.out.println("----------------cpu信息----------------");
        SystemInfo systemInfo = new SystemInfo();
        CentralProcessor processor = systemInfo.getHardware().getProcessor();
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        // 睡眠1s
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long[] ticks = processor.getSystemCpuLoadTicks();
        long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
        long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
        long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
        long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
        long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
        long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
        long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
        cpuVo.setCoreNum(processor.getLogicalProcessorCount());
        cpuVo.setUser_used(new DecimalFormat("#.##%").format(user * 1.0 / totalCpu));
        cpuVo.setSystem_used(new DecimalFormat("#.##%").format(cSys * 1.0 / totalCpu));
        cpuVo.setFree(new DecimalFormat("#.##%").format(1.0 - (idle * 1.0 / totalCpu)));
//        System.out.println("----------------cpu信息----------------");
//        System.out.println("cpu核数:" + processor.getLogicalProcessorCount());
//        System.out.println("cpu系统使用率:" + new DecimalFormat("#.##%").format(cSys * 1.0 / totalCpu));
//        System.out.println("cpu用户使用率:" + new DecimalFormat("#.##%").format(user * 1.0 / totalCpu));
//        System.out.println("cpu当前等待率:" + new DecimalFormat("#.##%").format(iowait * 1.0 / totalCpu));
//        System.out.println("cpu当前使用率:" + new DecimalFormat("#.##%").format(1.0-(idle * 1.0 / totalCpu)));
        return cpuVo;
    }

    public static MemVo MemInfo() {
        MemVo memVo = new MemVo();
//        System.out.println("----------------主机内存信息----------------");
        SystemInfo systemInfo = new SystemInfo();
        GlobalMemory memory = systemInfo.getHardware().getMemory();
        //总内存
        long totalByte = memory.getTotal();
        //剩余
        long acaliableByte = memory.getAvailable();
        memVo.setNum_size(formatByte(totalByte));
        memVo.setUsed_size(formatByte(totalByte - acaliableByte));
        memVo.setLeftover_size(formatByte(acaliableByte));
        memVo.setUsed(new DecimalFormat("#.##%").format((totalByte - acaliableByte) * 1.0 / totalByte));
//        System.out.println("总内存 = " + formatByte(totalByte));
//        System.out.println("使用" + formatByte(totalByte - acaliableByte));
//        System.out.println("剩余内存 = " + formatByte(acaliableByte));
//        System.out.println("使用率：" + new DecimalFormat("#.##%").format((totalByte - acaliableByte) * 1.0 / totalByte));
        return memVo;
    }

    public static ServerVo setSysInfo() {
        ServerVo serverVo = new ServerVo();
//        System.out.println("----------------操作系统信息----------------");
        Properties props = System.getProperties();
        //系统名称
        String osName = props.getProperty("os.name");
        //架构名称
        String osArch = props.getProperty("os.arch");
        String ip = "";
        String name = "";
        try {
            // 获取IP地址
            ip = InetAddress.getLocalHost().getHostAddress();
            // 获取计算机名
            name = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        serverVo.setName(name);
        serverVo.setIp(ip);
        serverVo.setSystem(osName);
        serverVo.setFramework(osArch);
//        System.out.println("操作系统名 = " + osName);
//        System.out.println("系统架构 = " + osArch);
        return serverVo;
    }

    public static JVMVo setJvmInfo() {
        Properties prop = System.getProperties();
//        System.out.println("----------------jvm信息----------------");
        //获取java名称
        String javaName = prop.getProperty("java.vm.name");
        //获取java的版本
        String javaVersion = prop.getProperty("java.version");
        //获取java的安装目录
        String javaPath = prop.getProperty("java.home");
        //获取项目的目录
        String filePath = prop.getProperty("user.dir");
        //获取java虚拟机启动时间
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        Date startTime = new Date(time);
        //获取java虚拟机运行时间
        long runTime = System.currentTimeMillis() - time;
        JVMVo jvmVo = new JVMVo(javaName,javaVersion,javaPath,filePath,startTime,runTime);


//        Properties props = System.getProperties();
//        System.out.println(System.getProperty("installDir"));
        Runtime runtime = Runtime.getRuntime();
        //jvm总内存
        long jvmTotalMemoryByte = runtime.totalMemory();
        //jvm最大可申请
        long jvmMaxMoryByte = runtime.maxMemory();
        //空闲空间
        long freeMemoryByte = runtime.freeMemory();
//        //jdk版本
//        String jdkVersion = props.getProperty("java.version");
//        //jdk路径
//        String jdkHome = props.getProperty("java.home");
        jvmVo.setNum_size(formatByte(jvmTotalMemoryByte));
        jvmVo.setUsed_size(formatByte(jvmTotalMemoryByte - freeMemoryByte));
        jvmVo.setLeftover_size(formatByte(freeMemoryByte));
        jvmVo.setUsed(new DecimalFormat("#.##%").format((jvmTotalMemoryByte - freeMemoryByte) * 1.0 / jvmTotalMemoryByte));
//        System.out.println("jvm内存总量 = " + formatByte(jvmTotalMemoryByte));
//        System.out.println("jvm已使用内存 = " + formatByte(jvmTotalMemoryByte - freeMemoryByte));
//        System.out.println("jvm剩余内存 = " + formatByte(freeMemoryByte));
//        System.out.println("jvm内存使用率 = " + new DecimalFormat("#.##%").format((jvmTotalMemoryByte - freeMemoryByte) * 1.0 / jvmTotalMemoryByte));
//        System.out.println("java版本 = " + jdkVersion);
        //System.out.println("jdkHome = " + jdkHome);
        return jvmVo;
    }

    public static void getThread() {
        System.out.println("----------------线程信息----------------");
        ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();

        while (currentGroup.getParent() != null) {
            // 返回此线程组的父线程组
            currentGroup = currentGroup.getParent();
        }
        //此线程组中活动线程的估计数
        int noThreads = currentGroup.activeCount();

        Thread[] lstThreads = new Thread[noThreads];
        //把对此线程组中的所有活动子组的引用复制到指定数组中。
        currentGroup.enumerate(lstThreads);
        for (Thread thread : lstThreads) {
            System.out.println("线程数量：" + noThreads + " 线程id：" + thread.getId() + " 线程名称：" + thread.getName() + " 线程状态：" + thread.getState());
        }
    }

    public static String formatByte(long byteNumber){
        //换算单位
        double FORMAT = 1024.0;
        double kbNumber = byteNumber/FORMAT;
        if(kbNumber<FORMAT){
            return new DecimalFormat("#.##KB").format(kbNumber);
        }
        double mbNumber = kbNumber/FORMAT;
        if(mbNumber<FORMAT){
            return new DecimalFormat("#.##MB").format(mbNumber);
        }
        double gbNumber = mbNumber/FORMAT;
        if(gbNumber<FORMAT){
            return new DecimalFormat("#.##GB").format(gbNumber);
        }
        double tbNumber = gbNumber/FORMAT;
        return new DecimalFormat("#.##TB").format(tbNumber);
    }

    public static void main(String[] args) {
        //获取java名称
        String javaName = System.getProperties().getProperty("java.vm.name");
        //获取java的版本
        String javaVersion = System.getProperties().getProperty("java.version");
        //获取java的安装目录
        String javaPath = System.getProperties().getProperty("java.home");
        //获取项目的目录
        String filePath = System.getProperties().getProperty("user.dir");
        //获取java虚拟机启动时间
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        Date startTime = new Date(time);
        //获取java虚拟机运行时间
        long runTime = System.currentTimeMillis() - time;
        System.out.println(filePath);
    }

}
